import axios, { AxiosInstance, AxiosRequestHeaders } from "axios"
import { getToken } from "../cache/cookies"
import { Router } from "vue-router"
import { ElMessage } from "element-plus"
import qs from "qs"

export default function setupAxios(router?: Router) {
  const instance: AxiosInstance | any = axios.create({
    timeout: 300000,
    headers: { Authorization: "Bearer " + getToken(), "Content-Type": "application/json;charset=UTF-8" },
    transformRequest: [
      function (data, headers) {
        headers["Authorization"] = "Bearer " + localStorage.getItem("token")
        return JSON.stringify(data)
      }
    ]
  })
  instance.myConfig = {
    get: async <T = any>(option: any) => {
      const res = await instance.get(option.url, { params: option.params })
      return res.data as unknown as T
    },
    post: async <T = any>(option: any) => {
      const res = await instance.post(option.url, option.data)
      return res.data as unknown as T
    },
    postOriginal: async (option: any) => {
      const res = await instance.post(option.url, option.data)
      return res
    },
    delete: async <T = any>(option: any) => {
      const res = await instance.delete(option.url, { params: option.params })
      return res.data as unknown as T
    },
    put: async <T = any>(option: any) => {
      const res = await instance.put(option.url, option.data)
      return res.data as unknown as T
    },
    download: async <T = any>(option: any) => {
      const res = await instance.get(option.url, { params: option.params, responseType: "blob" })
      return res as unknown as Promise<T>
    },
    upload: async <T = any>(option: any) => {
      option.headersType = "multipart/form-data"
      const res = await instance.post(option.url, option.data, { headers: option.headers })
      return res as unknown as Promise<T>
    }
  }
  instance.interceptors.request.use(
    (config) => {
      // 若存在token则带token
      // config.headers.Authorization = token
      // 放行
      const params = config.params || {}
      const data = config.data || false
      if (
        config.method?.toUpperCase() === "POST" &&
        (config.headers as AxiosRequestHeaders)["Content-Type"] === "application/x-www-form-urlencoded"
      ) {
        config.data = qs.stringify(data)
      }
      // get参数编码
      if (config.method?.toUpperCase() === "GET" && params) {
        config.params = {}
        //将params拼接到url上，以uid=cs11&pwd=000000als&username=cs11&password=000000als 这个字格式拼接传递
        const paramsStr = qs.stringify(params, { allowDots: true })
        if (paramsStr) {
          config.url = config.url + "?" + paramsStr
        }
      }
      return config
    },
    (err) => {
      console.log("请求拦截=>", err)
      return err
    }
  )
  instance.interceptors.response.use(
    (res) => {
      if (res.data.code == 401) {
        instance
          .post(
            "/admin-api/system/auth/refresh-token",
            {},
            {
              params: {
                refreshToken: localStorage.getItem("refreshToken")
              }
            }
          )
          .then((response: any) => {
            if (response.data.code == 0) {
              // 说明refreshToken 还未过期，可以刷新用户token
              localStorage.setItem("token", response.data.data.accessToken)
              localStorage.setItem("refreshToken", response.data.data.refreshToken)
              return
            } else {
              ElMessage.warning("用户凭证失效，请重新登陆！")
              router!.push({ path: "/login" })
              return
            }
          })
        // ElMessage.warning("用户凭证失效，请重新登陆！")
        // router!.push({ path: "/login" })
        // return
      } else if (res.data.code == 904) {
        ElMessage.warning("模板错误，请重新下载模板")
      } else if (res.data.code == 500) {
        ElMessage.warning("服务器内部错误，请检查！")
      } else {
        return res
      }
    },
    (err) => {
      // 在请求错误时要做的事儿
      // 该返回的数据则是axios.catch(err)中接收的数据
      return Promise.reject(err)
    }
  )
  return instance
}
